package cn.b.sky.user.filter;

import javax.servlet.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class ImeCompositeFilter implements Filter {

  private List<? extends Filter> filters;

  public ImeCompositeFilter() {
    this.filters = new ArrayList<Filter>();
  }

  @Override
  public void destroy() {
    for (int i = this.filters.size(); i-- > 0;) {
      Filter filter = this.filters.get(i);
      filter.destroy();
    }
  }

  @Override
  public void init(FilterConfig config) throws ServletException {
    for (Filter filter : this.filters) {
      filter.init(config);
    }
  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
      ServletException {
    new VirtualFilterChain(chain, this.filters).doFilter(request, response);
  }

  public void setFilters(List<? extends Filter> filters) {
    this.filters = filters;
  }

  private static final class VirtualFilterChain implements FilterChain {
    
    private final FilterChain originalChain;

    private final List<? extends Filter> additionalFilters;

    private int currentPosition = 0;

    private VirtualFilterChain(FilterChain chain, List<? extends Filter> additionalFilters) {
      this.originalChain = chain;
      this.additionalFilters = additionalFilters;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
      if (this.currentPosition == this.additionalFilters.size()) {
        this.originalChain.doFilter(request, response);
      } else {
        this.currentPosition += 1;

        Filter nextFilter = this.additionalFilters.get(this.currentPosition - 1);
        nextFilter.doFilter(request, response, this);
      }
    }
  }
}
